const axios = require('axios');
const { db } = require('../db');
const { getRedisValue, setRedisValue } = require('../db/redis')
const cos = require('../service/tencos');
const { APPID, APPSECRET, GZHAPPID, GZHAPPSECRET, HSFChatAPPID, HSFChatAPPSECRET } = require('../config');
const { logger } = require('../utils/serviceLogger');
const { encodeMsg, decodeMsg, xml2js, resWXMsg } = require('../utils/wxEncrypt');
const crypto = require('crypto')
const wechat = require('wechat');

// 微信公众号服务器配置
const appId = "wxafd8ec7535068dba";
const encodingAesKey = "iC8Uwd1SM0eK4BofjQCKHUwvFD0EYIP15x3J3zIblsc";
const token = "FNT1W303PS1Z3CA87PY9RJTGRWQ1B3B8";
const wxsubscribeConfig = {
    token: token,
    appid: appId,
    encodingAESKey: encodingAesKey,
}

const accessTokenUrl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential';
const jscode2Session = 'https://api.weixin.qq.com/sns/jscode2session';
const WXaCodeUrl = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit';

/**
 * 获取小程序的access_token
 */
const getAccessToken = async () => {
    return new Promise((resolve, reject) => 
        axios.get(accessTokenUrl + '&appid=' + APPID + '&secret=' + APPSECRET).then((res) => {
            const dataObj = res.data;
            setRedisValue(APPID, dataObj.access_token, 7100);
            resolve(dataObj.access_token);
        }).catch((err) => {
            reject(err);
        })
    );
}

/**
 * 获取公众号access_token
 * @returns 
 */
const getGZHAccessToken = async () => {
    return new Promise((resolve, reject) => 
        axios.get(accessTokenUrl + '&appid=' + GZHAPPID + '&secret=' + GZHAPPSECRET).then((res) => {
            const dataObj = res.data;
            setRedisValue(GZHAPPID, dataObj.access_token, 7100);
            resolve(dataObj.access_token);
        }).catch((err) => {
            reject(err);
        })
    );
}

/**
 * 获取黄师傅AI聊天的access_token
 * @returns 
 */
const getHSFAIAccessToken = async () => {
    return new Promise((resolve, reject) => 
        axios.get(accessTokenUrl + '&appid=' + HSFChatAPPID + '&secret=' + HSFChatAPPSECRET).then((res) => {
            const dataObj = res.data;
            setRedisValue(HSFChatAPPID, dataObj.access_token, 7100);
            resolve(dataObj.access_token);
        }).catch((err) => {
            reject(err);
        })
    );
}

exports.getWXUserInfo = async (req, res) => {
    const wxRes = await getUserInfo(req.query.code);
    return res.send({
        code: wxRes.errcode == 0 ? 200 : wxRes.errcode,
        msg: wxRes.errcode == 0 ? 'success' : wxRes.errmsg,
        data: {
            openId: wxRes.data.openid,
            sessionKey: wxRes.data.session_key,
            unionId: wxRes.data.unionid
        }
    })
}

exports.getWXUserInfo2 = async (code) => {
    const wxRes = await getUserInfo(code);
    if (wxRes.openid) {
        return {
            code: 200,
            msg: 'success',
            data: {
                openId: wxRes.openid,
            }
        }
    } else {
        return {
            code: wxRes.errcode,
            msg: wxRes.errmsg
        }
    }
}

/**
 * 获取不限制的小程序码
 */
exports.getWXaCode = async (req, res) => {
    const userInfo = await getUserByEmail(req.auth.email);
    if (userInfo.wxcodeUrl) {
        res.send({
            code: 200,
            msg: '',
            data: {
                url: userInfo.wxcodeUrl
            }
        });
    }
    const userId = userInfo.id;
    let accessToken = await getRedisValue(APPID);
    if (!accessToken) {
        accessToken = await getAccessToken();
    }
    const imageUrl = await new Promise((resolve, reject) => {
        axios.post(WXaCodeUrl + '?access_token=' + accessToken, {
            scene: `id=${userId}&adTag=1`
        }, {
            responseType: 'arraybuffer'
        }).then(async res => {
            // 图片buffer 怎么处理
            const url = await uploadFile(userId, res.data);
            resolve(url); // 图片buffer
        }).catch(err => {
            reject(err);
        })
    });

    const sql = "update users set wxcodeUrl=? where email=?";
    db.query(sql, [imageUrl, req.auth.email], (err, results) => {
        if (err) {
            return res.send({
                status: 500,
                msg: err.message
            })
        }
    });

    res.send({
        code: 200,
        msg: '',
        data: {
            url: imageUrl
        }
    });
}

exports.subscribe = async (req, res) => {
    return res.send('success');
}

exports.notify = async (req, res) => {

    // return res.send(req.query.echostr);

    const bufferXMLString = Buffer.from(req.body).toString('utf-8');
    console.log('--------------------开始')
    console.log('req:::', bufferXMLString);
    console.log('--------------------结束')
    
    logger.info(req, {
        label: '微信消息推送：'
    });

    const xmlObj = await xml2js(bufferXMLString);
    let content = '';
    if (xmlObj) {
        if (xmlObj.MsgType == 'event') {
            if (xmlObj.Event == 'subscribe') {
                content = `欢迎关注
                本公众号主要包含三个方面的内容：跨境馆、超清壁纸、智能聊天。
                跨境馆是一个小程序，大家可以在里面买到全球各个国家免税店的商品，物美价廉，跨境零关税，正品溯源，海关监管，包邮到家，欢迎大家选购
                超清壁纸是一个提供免费壁纸的小程序，上面的壁纸可以无限次下载和使用，无版权，可商用，欢迎大家下载。
                透漏一个小秘密：可以直接在此公众号里发送消息，AI客服会回答您的任何问题，不信您可以试一试！或
                <a href="https://mp.weixin.qq.com/s/3PVKAsqYE8Qnpdr9Td_B7Q">点击查看ChatGPT使用指南</a>
                需要进ChatGPT交流群的，发送"进群"，添加群主微信，群主通过后拉你进群`;
            }
        } else if (xmlObj.MsgType == 'text') {
            if (xmlObj['Content'] == 'ChatGPT访问密码' || xmlObj['Content'] == 'ChatGPT 访问密码'
                || xmlObj['Content'] == 'chatgpt访问密码' || xmlObj['Content'] == 'chatgpt 访问密码') {
                    content = '入口码为：masterX，现在不需要访问密码了，请关注此公众号，及时获取最新的入口码和最新AI信息。<a href="https://mp.weixin.qq.com/s/3PVKAsqYE8Qnpdr9Td_B7Q">点击查看ChatGPT使用指南</a>';
                } else if (xmlObj['Content'] == '进群') {
                    content = '群主微信：mengxinxianhai，小号：XKSaturn';
                } else {
                    // 调用ai生成内容
                    content = await getAnswer(xmlObj['Content']);
                    // getAnswer(xmlObj['Content'], (answer) => {
                    //     if (answer) {
                    //         const resXml2 = resWXMsg({
                    //             FromUserName: xmlObj.ToUserName,
                    //             ToUserName: xmlObj.FromUserName,
                    //             CreateTime: Math.floor(Date.now() / 1000),
                    //             Content: answer
                    //         });
                    //         res.send(Buffer.from(resXml2));
                    //     }
                    // });
                }
        } else {
            // 其他类型的消息，非text和subscribe
            content = '不支持此类型消息';
        }
    }

    const resXml = resWXMsg({
        FromUserName: xmlObj.ToUserName,
        ToUserName: xmlObj.FromUserName,
        CreateTime: Math.floor(Date.now() / 1000),
        Content: content
    });
    const resXmlBuffer = Buffer.from(resXml);
    console.log('resXml', resXml);
    console.log('buffer resXml', resXmlBuffer)
    logger.info({}, { 
        label: '待发送的XML字符串：' + resXml
    })
    logger.info({}, { 
        label: '待发送的XML字符串Buffer' + resXmlBuffer
    })
    res.set({
        'Content-Type': 'text/plain',
    });
    return res.send(resXmlBuffer);

    const msg = await decodeMsg({
        msg_signature: req.query.msg_signature,
        timestamp: req.query.timestamp,
        nonce: req.query.nonce,
        postData: bufferXMLString
    });
    
    if (msg) {
        console.log('msg ToUserName:', msg.ToUserName);
        console.log('msg FromUserName', msg.FromUserName);
        console.log('msg CreateTime', msg.CreateTime);
        console.log('msg MsgType', msg.MsgType);
        console.log('msg Content', msg.Content);
        logger.info({}, {
            label: '微信消息解密后的内容：' + JSON.stringify(msg)
        });
        let resXmlObj = {
            originalMsg: msg,
            nonce: req.query.nonce,
        };
        if (msg.MsgType == 'event') {
            if (msg.Event == 'subscribe') {
                resXmlObj.msgText = `欢迎关注
                本公众号主要包含三个方面的内容：跨境馆、超清壁纸、智能聊天。
                跨境馆是一个小程序，大家可以在里面买到全球各个国家免税店的商品，物美价廉，跨境零关税，正品溯源，海关监管，包邮到家，欢迎大家选购
                超清壁纸是一个提供免费壁纸的小程序，上面的壁纸可以无限次下载和使用，无版权，可商用，欢迎大家下载。
                透漏一个小秘密：可以直接在此公众号里发送消息，AI客服会回答您的任何问题，不信您可以试一试！或
                <a href="https://mp.weixin.qq.com/s/3PVKAsqYE8Qnpdr9Td_B7Q">点击查看ChatGPT使用指南</a>
                需要进ChatGPT交流群的，发送"进群"，添加群主微信，群主通过后拉你进群`;
                // 组装xml
                const encryptResXml = encodeMsg(resXmlObj);
                
                if (encryptResXml) {
                    res.set({
                        'Content-Type': 'text/plain',
                    });
                    return res.send(encryptResXml);
                } else {
                    
                }
            }
        } else if (msg.MsgType == 'text') {
            if (msg['Content'] == 'ChatGPT访问密码' || msg['Content'] == 'ChatGPT 访问密码'
                || msg['Content'] == 'chatgpt访问密码' || msg['Content'] == 'chatgpt 访问密码') {
                    resXmlObj.msgText = '入口码为：masterX，现在不需要访问密码了，请关注此公众号，及时获取最新的入口码和最新AI信息。<a href="https://mp.weixin.qq.com/s/3PVKAsqYE8Qnpdr9Td_B7Q">点击查看ChatGPT使用指南</a>';
                    const encryptResXml = encodeMsg(resXmlObj);
                    if (encryptResXml) {
                        res.set({
                            'Content-Type': 'text/plain',
                        });
                        return res.send(encryptResXml);
                    } else {
                        
                    }
                } else if (msg['Content'] == '进群') {
                    resXmlObj.msgText = '群主微信：mengxinxianhai，小号：XKSaturn';
                    const encryptResXml = encodeMsg(resXmlObj);
                    if (encryptResXml) {
                        res.set({
                            'Content-Type': 'text/plain',
                        });
                        return res.send(encryptResXml);
                    } else {
                        
                    } 
                } else {
                    // 调用ai生成内容
                    resXmlObj.msgText = '欢迎您关注与发送消息';
                    const encryptResXml = encodeMsg(resXmlObj);
                    // const decryptResXml = decodeMsg(encryptResXml);
                    if (encryptResXml) {
                        res.set({
                            'Content-Type': 'text/plain',
                        });
                        return res.send(encryptResXml);
                    } else {
                        
                    } 
                }
        } else {
            // 其他类型的消息，非text和subscribe
            return 'ai';
        }
    }
    return res.send(req.query.echostr);
}

exports.checkContent = async (req, res) => {

}

const getAnswer = async (questionContent) => {
    const axiosRes = await axios.post('http://18.180.45.69:8686/chatgpt/ai-chat', {
        questionContent
    });
    logger.info('请求成功：', axiosRes.data);
    const realData = axiosRes.data;
    if (realData && realData.code == 200) {
        if (realData.data) {
            return realData.data.message;
        }
    }
}

const getUserByEmail = async (email) => {
    const sql = "select id, email, wxcodeUrl from users where email=?";
    return new Promise((resolve, reject) => {
        db.query(sql, email, (err, results) => {
            if (err) {
                reject(err);
            } else {
                resolve({
                    id: results[0].id,
                    email: results[0].email,
                    wxcodeUrl: results[0].wxcodeUrl
                });
            }
        })
    })
}

const uploadFile = async (fileName, fileBuffer) => {
    return new Promise((resolve, reject) => {
        // 获取年月日并进行拼接
        const date = new Date();
        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const day = date.getDate();
        const path = 'wxacode/' + year + '' + month + '' + day + '/' + fileName + '.png';
        cos.putObject({
            Bucket: 'xiaosaturn-1254446013',
            Region: 'ap-nanjing',
            Key: path,
            StorageClass: 'STANDARD',
            Body: Buffer.from(fileBuffer),
        }, (err, data) => {
            if (err) {
                console.log('上传失败', err);
                reject(err);
            } else {
                const url = 'https://image.xiaosaturn.com/' + path;
                resolve(url);
            }
        })
    });
}

const getUserInfo = async (code) => {
    let accessToken = await getRedisValue(APPID);
    if (!accessToken) {
        accessToken = await getAccessToken();
    }
    const wxRes = await new Promise((resolve, reject) => {
        axios.get(jscode2Session + '?appid=' + APPID + '&secret=' + APPSECRET + '&js_code=' + code + '&grant_type=authorization_code').
        then((res) => {
            resolve(res.data);
        }).catch((err) => {
            reject(err);
        })
    });
    return wxRes;
}
